package utils;

import java.util.*;

public class Grafo<Vertices> {

	private Vector <Integer> vertices;
	private Map<Integer,Vector<Arista>> aristas;

	public Grafo()
	{
		vertices = new Vector<Integer>();
		aristas = new HashMap<Integer,Vector<Arista>>();
	}
	public boolean esVacia()
	{
		return vertices.isEmpty();
	}
	
	public void insertarVectice (int vertice)
	{
		if (vertices.contains(vertice) == false)
			{
				vertices.addElement(vertice);
			}
	}
	
	public void insertarArista (int origen, int destino, Character operador )
	{
		Arista arista = new Arista();
		arista.setDestino(destino);
		arista.setCoste(operador);		
		boolean insertado = false;
		
		if(!vertices.contains(origen))
		{
			vertices.addElement(origen);
		}		
		if(!vertices.contains(destino))
		{
			vertices.addElement(destino);
		}		
		
		if (!aristas.containsKey(origen))
		{
			Vector<Arista> listaAux = new Vector<Arista>();
			listaAux.addElement(arista);
			aristas.put(origen, listaAux);
			insertado = true;
		} else 
		{
			aristas.get(origen).addElement(arista);
			insertado = false;
			
		}
		if (insertado)
		{
			if (!vertices.contains(destino))
				vertices.addElement(destino);
		}
		//vertices.
		
		
	}
	@SuppressWarnings("unchecked")
	public void ordenarVertices()
	{
		Vector<Integer> verticesOrdenados = new Vector<Integer>();
		
		Collections.sort(this.vertices);
		Iterator iter = this.vertices.iterator();
		while (iter.hasNext())
			verticesOrdenados.addElement((Integer) iter.next());
			//System.out.println(iter.next());
		this.vertices = new Vector<Integer>();
		this.vertices = verticesOrdenados;
	}
	public void mostrarGrafo()
	{
		
		// ordenamos los vertices
		for (int i = 0 ; i<vertices.size() ; i++)
		{
			System.out.print(vertices.elementAt(i));
			if (!aristas.isEmpty() && aristas.containsKey(vertices.elementAt(i)))
			{
				Vector<Arista> aris = aristas.get(vertices.elementAt(i));
				if (aris == null)
				{
					System.out.println();
					
				}else{
					if (!aris.isEmpty())
					{
						for (int j = 0 ; j<aris.size() ; j++)
						{
							System.out.print(" => " + aris.elementAt(j).getDestino() + "(" + aris.elementAt(j).getCoste() + ")");
						}
					}
				}
			}
			System.out.println();
		}
		System.out.println();
	}
	public void setListaVertices(Vector<Integer> verticesNuevos)
	{
		this.vertices = new Vector<Integer>();
		for (int i = 0 ; i < verticesNuevos.size();i++)
		{
			vertices.addElement(verticesNuevos.elementAt(i));
		}
	}
	public Character obtenerCoste(int origen, int destino)
	{
		if (vertices.contains(origen)&&vertices.contains(destino))
		{
			Vector<Arista> arista = aristas.get(origen);
			for (int i=0; i<arista.size();i++)
			{
				if (arista.elementAt(i).getDestino() == destino)
				{
					return arista.elementAt(i).getCoste();
				}
			}
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public Vector<Vertices> listaSucesores(int clave)
	{
		return (Vector<Vertices>) aristas.get(clave);
	}
	@SuppressWarnings("unchecked")
	public int obtenerSucesores(int estadoInicial, char simbolo){
		Vector v = new Vector();
		
		v = this.listaSucesores(estadoInicial);
		if (v == null)
			return -1;
		Iterator it = v.iterator();
		while (it.hasNext()){
			Arista ar = (Arista)it.next();
			if (ar.getCoste() == simbolo)
				return ar.getDestino();
		}
		return -1;
	}
	
	public Vector<Integer> listaVertices()
	{
		return vertices;
	}
	public void duplicarArista(int estado, Vector<Arista> aristasFinales)
	{
		
		if (!vertices.contains(estado))
		{
			if (aristasFinales != null){
				for (int x = 0 ; x < aristasFinales.size() ; x++)
				{
					aristasFinales.elementAt(x).setDestino(aristasFinales.elementAt(x).getDestino()+estado);
				}
			}
			vertices.addElement(estado);
			aristas.put(estado, aristasFinales);
			return;
		}
		if (aristas.get(estado) == null)
		{
			if (aristasFinales != null){
				for (int x = 0 ; x < aristasFinales.size() ; x++)
				{
					aristasFinales.elementAt(x).setDestino(aristasFinales.elementAt(x).getDestino()+estado);
				}
			}
			aristas.put(estado, aristasFinales);
		} else
		{
			for (int i = 0 ; i<aristasFinales.size(); i++)
			{
				if (!aristas.get(estado).contains(aristasFinales.elementAt(i).getDestino()))
				{
					aristasFinales.elementAt(i).setDestino(aristasFinales.elementAt(i).getDestino() + estado);
					//System.out.println("AAAA " + aristasFinales.elementAt(i).getDestino());
					aristas.get(estado).addElement(aristasFinales.elementAt(i));
				}
			}
		}
	}
}
